package com.eastfair.auth.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.eastfair.auth.dao.MenuRoleMapper;
import com.eastfair.auth.entity.MenuRole;
import com.eastfair.auth.service.MenuRoleService;
import com.eastfair.boot.service.SuperCacheServiceImpl;
import com.eastfair.businpoint.BusinLoadUserPermissOfRolePoint;
import com.eastfair.businpoint.BusinLoadUserPermissPoint;
import com.eastfair.cache.auth.MenuRoleCacheKeyBuilder;
import com.eastfair.cache.repository.CacheOps;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.model.CacheKeyBuilder;
import com.eastfair.core.snowflake.DefaultUidGenerator;
import com.eastfair.log.point.PointUtil;
import com.eastfair.projectcore.api.ProjectCoreServiceFeign;
import com.eastfair.core.snowflake.DefaultUidGenerator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 业务实现类
 *
 * </p>
 *
 * @author ligang
 * @date 2021-07-23
 */
@Slf4j
@Service
@DS("#thread.tenant")
public class MenuRoleServiceImpl extends SuperCacheServiceImpl<MenuRoleMapper, MenuRole> implements MenuRoleService {
    @Autowired
    protected CacheOps cacheOps;
    @Autowired
    ProjectCoreServiceFeign projectCoreServiceFeign;

    @Autowired
    PointUtil pointUtil;

    /**************sharding 分库分表操作 *****************/
    @Override
    public boolean updateByIdOfShard(MenuRole entity) {
        UpdateWrapper<MenuRole> updateWrapper = new UpdateWrapper<>();
        //可将指定字段更新为null
        updateWrapper.lambda().eq(MenuRole::getProjectId, entity.getProjectId()).eq(MenuRole::getId, entity.getId());
        entity.setProjectId(null);
        //删除缓存
        delCache(entity);
        return SqlHelper.retBool(this.getBaseMapper().update(entity, updateWrapper));
    }

    @Override
    protected CacheKeyBuilder cacheKeyBuilder() {
        return new MenuRoleCacheKeyBuilder();
    }

    /**
     * 处理新增相关处理
     *
     * @param model 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerSave(MenuRole model) {
        //雪花ID
        if (model.getProjectId() == null) {
            model.setProjectId(ContextUtil.getProjectId());
        }
        model.setId(DefaultUidGenerator.getUidOfProjectId(model.getProjectId()));
        return R.successDef();
    }

    @Override
    public R addOfMenu(Long roleId, List<Long> menuIds) {
        if (menuIds != null && !menuIds.isEmpty()) {
            MenuRole menuRole = new MenuRole();
            menuRole.setRoleId(roleId);
            List<MenuRole> menuRoleList = list(menuRole, null, null);
            //剔除已经存在的
            if (menuRoleList != null && !menuRoleList.isEmpty()) {
                List<Long> oldmenuIds = menuRoleList.stream().map(MenuRole::getMenuId).collect(Collectors.toList());
                menuIds.removeAll(oldmenuIds);
            }
            if (menuIds != null && !menuIds.isEmpty()) {
                for (Long menuId : menuIds) {
                    MenuRole menuRole1 = new MenuRole();
                    menuRole1.setMenuId(menuId);
                    menuRole1.setRoleId(roleId);
                    save(menuRole1);
                }
            }

            //添加到事件监听队列

            BusinLoadUserPermissOfRolePoint businLoadUserPermissOfRolePoint = new BusinLoadUserPermissOfRolePoint();
            businLoadUserPermissOfRolePoint.setRoleIdList(Arrays.asList(roleId));
            businLoadUserPermissOfRolePoint.setProjectId(ContextUtil.getProjectId());
            pointUtil.addBusinPointMsg(businLoadUserPermissOfRolePoint);

        }
        return R.success();
    }


    @Override
    public List<MenuRole> list(MenuRole menuRole, List<Long> menuIds, List<Long> roleIds) {
        //查询
        QueryWrapper<MenuRole> queryWrapper = new QueryWrapper<>();
        if (menuRole != null) {
            if (menuRole.getId() != null) {
                queryWrapper.lambda().eq(MenuRole::getId, menuRole.getId());
            }
            if (menuRole.getRoleId() != null) {
                queryWrapper.lambda().eq(MenuRole::getRoleId, menuRole.getRoleId());
            }

            if (menuRole.getMenuId() != null) {
                queryWrapper.lambda().eq(MenuRole::getMenuId, menuRole.getMenuId());
            }
        }
        if (menuRole != null && menuRole.getProjectId() != null) {
            queryWrapper.lambda().eq(MenuRole::getProjectId, menuRole.getProjectId());
        } else if (ContextUtil.getProjectId() != null) {
            queryWrapper.lambda().eq(MenuRole::getProjectId, ContextUtil.getProjectId());
        }


        if (menuIds != null && !menuIds.isEmpty()) {
            queryWrapper.lambda().in(MenuRole::getMenuId, menuIds);
        }
        if (roleIds != null && !roleIds.isEmpty()) {
            queryWrapper.lambda().in(MenuRole::getRoleId, roleIds);
        }
        queryWrapper.lambda().eq(MenuRole::getIsDeleted, BusinessConstant.DELETE_NO);
        List<MenuRole> menuRoleList = list(queryWrapper);
        return menuRoleList;
    }


    @Override
    public R removeMenuRole(Long menuId, List<Long> roleIds) {
        MenuRole menuRole = new MenuRole();
        menuRole.setMenuId(menuId);
        List<MenuRole> menuRoleList = list(menuRole, null, roleIds);
        if (menuRoleList != null && !menuRoleList.isEmpty()) {
            for (MenuRole menuRole1 : menuRoleList) {
                menuRole1.setIsDeleted(BusinessConstant.DELETE_YES);
                updateByIdOfShard(menuRole1);
            }

            //添加到事件监听队列
            BusinLoadUserPermissOfRolePoint businLoadUserPermissOfRolePoint = new BusinLoadUserPermissOfRolePoint();
            businLoadUserPermissOfRolePoint.setRoleIdList(menuRoleList.stream().map(MenuRole::getRoleId).collect(Collectors.toList()));
            businLoadUserPermissOfRolePoint.setProjectId(ContextUtil.getProjectId());
            pointUtil.addBusinPointMsg(businLoadUserPermissOfRolePoint);
        }
        return R.success();
    }

    @Override
    public R removeRole(List<Long> roleIds) {
        List<MenuRole> menuRoleList = list(null, null, roleIds);
        if (menuRoleList != null && !menuRoleList.isEmpty()) {
            for (MenuRole menuRole1 : menuRoleList) {
                menuRole1.setIsDeleted(BusinessConstant.DELETE_YES);
                updateByIdOfShard(menuRole1);
            }
        }

        //添加到事件监听队列
        BusinLoadUserPermissOfRolePoint businLoadUserPermissOfRolePoint = new BusinLoadUserPermissOfRolePoint();
        businLoadUserPermissOfRolePoint.setRoleIdList(roleIds);
        businLoadUserPermissOfRolePoint.setProjectId(ContextUtil.getProjectId());
        pointUtil.addBusinPointMsg(businLoadUserPermissOfRolePoint);

        return R.success();
    }

    @Override
    public R removeMenu(List<Long> menuIds) {
        List<MenuRole> menuRoleList = list(null, menuIds, null);
        if (menuRoleList != null && !menuRoleList.isEmpty()) {
            for (MenuRole menuRole1 : menuRoleList) {
                menuRole1.setIsDeleted(BusinessConstant.DELETE_YES);
                updateByIdOfShard(menuRole1);
            }
        }
        return R.success();
    }

    @Override
    public R<List<MenuRole>> findOfRole(List<Long> roleIds) {
        return R.success(list(null, null, roleIds));
    }
}
